﻿using SHZY.Common.Core.Manager;
using SHZY.Common.Core.Security;
using SHZY.Common.Enum;
using SHZY.Common.Extension;
using SHZY.Common.Filter;
using SHZY.Common.Models;
using SHZY.Common.Security;
using SHZY.DependencyInjection;
using SHZY.DynamicApiController;
using SHZY.FriendlyException;
using SHZY.Systems.Entitys.Permission;
using SHZY.Systems.Entitys.System;
using SHZY.Systems.Interfaces.System;
using SHZY.Business.Entitys.Dto.QmsBusiIpqcinspection;
using SHZY.Business.Entitys;
using SHZY.Business.Interfaces;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using Npgsql.Replication.PgOutput.Messages;
using SHZY.ClayObject;
using SHZY.Common.Configuration;
using SHZY.Common.Models.NPOI;
using SHZY.DataEncryption;
using System.Linq;
using Aspose.Cells;
using SHZY.BaseData.Entitys;
using SHZY.BaseData.Entitys.Entity;
using Yitter.IdGenerator;
using SHZY.BaseData.Entitys.Dto.QmsBaseCheckcarddetail;
using SHZY.BaseData.Entitys.Entity.Samplingplan;
using Newtonsoft.Json.Linq;
using SHZY.Business.Entitys.Dto.QmsBusiInspectionlot;
using Org.BouncyCastle.Crypto;
using SHZY.BaseData.Entitys.Entity.QmsBaseIpqccalendar;
using SHZY.Message.Interfaces.Message;
using SHZY.Business.Entitys.Dto.QmsBusiIpqcinspectionlot;
using NPOI.SS.Formula.Functions;

namespace SHZY.Business;

/// <summary>
/// 业务实现：制程报检单.
/// </summary>
[ApiDescriptionSettings(Tag = "Business", Name = "IpqcInspection", Order = 200)]
[Route("api/Business/[controller]")]
public class QmsBusiIpqcinspectionService : IQmsBusiIpqcinspectionService, IDynamicApiController, ITransient
{
    /// <summary>
    /// 服务基础仓储.
    /// </summary>
    private readonly ISqlSugarRepository<QmsBusiIpqcinspectionEntity> _repository;
    /// <summary>
    /// 用户管理.
    /// </summary>
    private readonly IUserManager _userManager;
    /// <summary>
    /// 数据字典服务.
    /// </summary>
    private readonly IDictionaryDataService _dictionaryDataService;

    /// <summary>
    /// 单据编号服务
    /// </summary>
    private readonly IBillRullService _billRullService;

    private readonly IMessageService _messageService;

    /// <summary>
    /// 初始化一个<see cref="QmsBusiIpqcinspectionService"/>类型的新实例.
    /// </summary>
    public QmsBusiIpqcinspectionService(
        ISqlSugarRepository<QmsBusiIpqcinspectionEntity> qmsBusiIpqcinspectionRepository,
        ISqlSugarClient context,
        IBillRullService billRullService,
        IUserManager userManager,
        IDictionaryDataService dictionaryDataService, IMessageService messageService)
    {
        _repository = qmsBusiIpqcinspectionRepository;
        _billRullService = billRullService;
        _userManager = userManager;
        _dictionaryDataService = dictionaryDataService;
        _messageService = messageService;
    }

    /// <summary>
    /// 获取制程报检单.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <returns></returns>
    [HttpGet("{id}")]
    public async Task<dynamic> GetInfo(string id)
    {

        var data = await _repository.FirstOrDefaultAsync(x => x.Id == id);
        var userInfo = await _repository.Context.Queryable<UserEntity>().Where(it => it.Account == data.EmployeeCode&& it.DeleteMark == null).FirstAsync();
        data.EmployeeCode = userInfo.Id;
        return data.Adapt<QmsBusiIpqcinspectionInfoOutput>();
    }

    /// <summary>
    /// 获取制程报检单列表.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("")]
    public async Task<dynamic> GetList([FromQuery] QmsBusiIpqcinspectionListQueryInput input)
    {
        var queryable = _repository.Context.Queryable<QmsBusiIpqcinspectionEntity, QmsBaseMaterialEntity, QmsBaseCheckcardEntity>((it, b, c) => new JoinQueryInfos(JoinType.Left, it.MaterialCode == b.Code && b.DeleteMark == null, JoinType.Left, it.InspectionCase == c.Id))
             .WhereIF(!string.IsNullOrEmpty(input.code), it => it.Code.Contains(input.code))
             .WhereIF(!string.IsNullOrEmpty(input.type), it => it.Type.Equals(input.type))
             .WhereIF(input.status != null, it => it.Status.Equals(input.status))
             .WhereIF(!string.IsNullOrEmpty(input.materialCode), it => it.MaterialCode.Contains(input.materialCode))
             .WhereIF(!string.IsNullOrEmpty(input.orderNo), it => it.OrderNo.Contains(input.orderNo))
             .WhereIF(!string.IsNullOrEmpty(input.employeeCode), it => it.EmployeeCode.Contains(input.employeeCode))
             .WhereIF(!string.IsNullOrEmpty(input.keyword), it => it.Code.Contains(input.keyword) || it.Type.Contains(input.keyword) || it.MaterialCode.Contains(input.keyword) || it.EmployeeCode.Contains(input.keyword))
              .Where(it => it.DeleteMark == null)
              .Select((it, b, c) => new QmsBusiIpqcinspectionListOutput
              {
                  id = it.Id,
                  type = it.Type,
                  code = it.Code,
                  date = it.Date,
                  workshopId = it.WorkshopId,
                  teamId = it.TeamId,
                  workshopSectionId = it.WorkshopSectionId,
                  stationId = it.StationId,
                  processIdList = it.ProcessIdList,
                  materialCode = SqlFunc.MergeString(b.Name, " " + it.MaterialCode),
                  inspectionCase = c.Name,
                  productionQty = it.ProductionQty,
                  employeeCode = it.EmployeeCode,
                  employeeName = it.EmployeeName,
                  orderNo = it.OrderNo,
                  remark = it.Remark,
                  status = it.Status,
                  overdue = it.Overdue,
                  closeFlag = it.CloseFlag,
                  dayFlag = it.DayFlag,
                  dayValue = it.DayValue,
                  hourFlag = it.HourFlag,
                  hourValue = it.HourValue,
              }).MergeTable();

        if (!string.IsNullOrEmpty(input.sidx))
        {
            queryable.OrderBy(input.sidx + " " + input.sort);
        }
        else
        {
            queryable.OrderBy(it=>it.status);
        }
        var data = await queryable.ToPagedListAsync(input.currentPage, input.pageSize);

        var factoryList = await _repository.Context.Queryable<QmsBaseFactorystructureEntity>().Where(x => x.DeleteMark == null).ToListAsync();
        var stationList = await _repository.Context.Queryable<QmsBaseStationEntity>().Where(x => x.DeleteMark == null).ToListAsync();

        foreach (var item in data.list)
        {
            item.workshopId = factoryList.Find(x => x.Id.Equals(item.workshopId))?.FullName;
            item.teamId = factoryList.Find(x => x.Id.Equals(item.teamId))?.FullName;
            item.workshopSectionId = factoryList.Find(x => x.Id.Equals(item.workshopSectionId))?.FullName;
            item.stationId = stationList.Find(x => x.Id.Equals(item.stationId))?.FullName;
            if (!string.IsNullOrEmpty(item.processIdList))
            {
                string[] processIdList = item.processIdList.Split(',');
                var processNameList = await _repository.Context.Queryable<QmsBaseArtroutedetailEntity>().Where(x => processIdList.Contains(x.Id) && x.DeleteMark == null).Select(x => x.FullName).ToListAsync();
                item.processIdList = string.Join(",", processNameList);
            }

        }



        return PageResult<QmsBusiIpqcinspectionListOutput>.SqlSugarPageResult(data);
    }

    /// <summary>
    /// 新建制程报检单.
    /// </summary>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPost("")]
    public async Task Create([FromBody] List<QmsBusiIpqcinspectionCrInput> input)
    {
        var entityList = input.Adapt<List<QmsBusiIpqcinspectionEntity>>();
        var index = 1;
        foreach (var entity in entityList)
        {
            if (string.IsNullOrEmpty(entity.EmployeeCode))
            {
                if (!GetInspector(entity).Result)
                {
                    throw Oops.Oh("第" + index + "行的报检单未匹配到检验员，请确认");
                }
            }
            else
            {
                var userInfo = await _repository.Context.Queryable<UserEntity>().Where(it => it.Id == entity.EmployeeCode).FirstAsync();
                entity.EmployeeCode = userInfo.Account;
                entity.EmployeeName = userInfo.RealName;

            }
            index++;
        }
        // 数据通过后获取报检单号
        foreach (var entity in entityList)
        {
            entity.Code= await _billRullService.GetBillNumber("zhichengbaojiandan");
        }
        var isOk = await _repository.Context.Insertable(entityList).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
        if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1000);
    }
    /// <summary>
    /// 获取检验员
    /// </summary>
    /// <returns></returns>
    private async Task<bool> GetInspector(QmsBusiIpqcinspectionEntity entity)
    {
        string[] processIdList = entity.ProcessIdList.Split(',');

        var queryable = _repository.Context.Queryable<QmsBaseIpqcinspectorEntity>()
             .WhereIF(!string.IsNullOrEmpty(entity.Type), x => x.Type == entity.Type);

        // 工厂信息不为空则需要添加工厂信息条件进行匹配检验员
        if (!string.IsNullOrEmpty(entity.WorkshopId) || !string.IsNullOrEmpty(entity.TeamId) || !string.IsNullOrEmpty(entity.WorkshopSectionId) || !string.IsNullOrEmpty(entity.StationId))
        {
            if (!string.IsNullOrEmpty(entity.StationId))
            {
                // 查询工位这个层级是否能匹配到检验员数据
                if (await queryable.Where(x => x.StationId == entity.StationId).CountAsync() > 0)
                {
                    queryable = queryable.Where(x => x.StationId == entity.StationId);
                }
                else
                {
                    queryable=queryable.Where(x => x.StationId == "");
                }
            }
            else
            {
                queryable = queryable.Where(x => x.StationId == "");
            }

            if (await queryable.WhereIF(!string.IsNullOrEmpty(entity.WorkshopId), x => x.WorkshopId == entity.WorkshopId)
                   .WhereIF(!string.IsNullOrEmpty(entity.TeamId), x => x.TeamId == entity.TeamId)
                   .WhereIF(string.IsNullOrEmpty(entity.TeamId), x => x.TeamId == "")
                   .WhereIF(!string.IsNullOrEmpty(entity.WorkshopSectionId), x => x.WorkshopSectionId == entity.WorkshopSectionId)
                   .WhereIF(string.IsNullOrEmpty(entity.WorkshopSectionId), x => x.WorkshopSectionId == "").CountAsync() > 0)
            {
                queryable = queryable.WhereIF(!string.IsNullOrEmpty(entity.WorkshopId), x => x.WorkshopId == entity.WorkshopId)
                   .WhereIF(!string.IsNullOrEmpty(entity.TeamId), x => x.TeamId == entity.TeamId)
                   .WhereIF(string.IsNullOrEmpty(entity.TeamId), x => x.TeamId == "")
                   .WhereIF(!string.IsNullOrEmpty(entity.WorkshopSectionId), x => x.WorkshopSectionId == entity.WorkshopSectionId)
                   .WhereIF(string.IsNullOrEmpty(entity.WorkshopSectionId), x => x.WorkshopSectionId == "");
            }
            else
            {
                // 匹配不到数据则报异常
                return false;
            }
        }


        var ipqcInspector = new QmsBaseIpqcinspectorEntity();

        // 先查询最小匹配
        if (!string.IsNullOrEmpty(entity.MaterialCode) && !string.IsNullOrEmpty(entity.ProcessIdList))
        {
            ipqcInspector = await queryable.Where(x => x.MaterialCode == entity.MaterialCode && processIdList.Contains(x.ProcessId)).OrderBy(x => x.CreatorTime, OrderByType.Desc).FirstAsync();
        }
        else if (!string.IsNullOrEmpty(entity.MaterialCode))
        {
            ipqcInspector = await queryable.Where(x => x.MaterialCode == entity.MaterialCode).OrderBy(x => x.CreatorTime, OrderByType.Desc).FirstAsync();
        }
        else if (!string.IsNullOrEmpty(entity.ProcessIdList))
        {
            ipqcInspector = await queryable.Where(x => processIdList.Contains(x.ProcessId)).OrderBy(x => x.CreatorTime, OrderByType.Desc).FirstAsync();
        }
        // 最小匹配不到再查最大
        if (ipqcInspector == null)
        {
            // 查询工艺路线信息
            var artrouteList = new List<string>();
            if (!string.IsNullOrEmpty(entity.ProcessIdList))
            {
                artrouteList = await _repository.Context.Queryable<QmsBaseArtroutedetailEntity>().Where(x => processIdList.Contains(x.Id) && x.EnabledMark == 1 && x.DeleteMark == null).Select(x => x.ParentId).ToListAsync();
            }
            // 查询物料组信息
            var materialGroupCode = "";
            if (!string.IsNullOrEmpty(entity.MaterialCode))
            {
                materialGroupCode = (await _repository.Context.Queryable<QmsBaseMaterialEntity>().Where(x => x.Code == entity.MaterialCode && x.EnabledMark == 1 && x.DeleteMark == null).FirstAsync()).MaterialGroupCode;
            }

            if (!string.IsNullOrEmpty(entity.MaterialCode) && !string.IsNullOrEmpty(entity.ProcessIdList))
            {
                ipqcInspector = await queryable.Where(x => x.MaterialGroupCode == materialGroupCode && string.IsNullOrEmpty(x.MaterialCode) && artrouteList.Contains(x.ArtrouteId) && string.IsNullOrEmpty(x.ProcessId)).FirstAsync();
            }
            else if (!string.IsNullOrEmpty(entity.MaterialCode))
            {
                ipqcInspector = await queryable.Where(x => x.MaterialGroupCode == materialGroupCode && string.IsNullOrEmpty(x.MaterialCode)).OrderBy(x => x.CreatorTime, OrderByType.Desc).FirstAsync();
            }
            else if (!string.IsNullOrEmpty(entity.ProcessIdList))
            {
                ipqcInspector = await queryable.Where(x => artrouteList.Contains(x.ArtrouteId) && string.IsNullOrEmpty(x.ProcessId)).OrderBy(x => x.CreatorTime, OrderByType.Desc).FirstAsync();
            }

            if (ipqcInspector == null)
            {
                return false;
            }
            entity.EmployeeCode = ipqcInspector.EmployeeCode;
            entity.EmployeeName = (await _repository.Context.Queryable<UserEntity>().Where(x => x.Account == ipqcInspector.EmployeeCode).FirstAsync()).RealName;
        }
        else
        {
            return false;
        }
        return true;
    }

    /// <summary>
    /// 获取制程报检单无分页列表.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    private async Task<dynamic> GetNoPagingList([FromQuery] QmsBusiIpqcinspectionListQueryInput input)
    {
        var queryable = _repository.Context.Queryable<QmsBusiIpqcinspectionEntity>()
            .WhereIF(!string.IsNullOrEmpty(input.code), it => it.Code.Contains(input.code))
            .WhereIF(!string.IsNullOrEmpty(input.type), it => it.Type.Equals(input.type))
            .WhereIF(!string.IsNullOrEmpty(input.materialCode), it => it.MaterialCode.Contains(input.materialCode))
            .WhereIF(!string.IsNullOrEmpty(input.employeeCode), it => it.EmployeeCode.Contains(input.employeeCode))
            .WhereIF(!string.IsNullOrEmpty(input.keyword), it => it.Code.Contains(input.keyword) || it.Type.Contains(input.keyword) || it.MaterialCode.Contains(input.keyword) || it.EmployeeCode.Contains(input.keyword))
            .Where(a => a.DeleteMark == null)
            .OrderByIF(string.IsNullOrEmpty(input.sidx), it => it.Id);
        if (!string.IsNullOrEmpty(input.sidx))
        {
            queryable.OrderBy(input.sidx + " " + input.sort);
        }
        var data = await queryable.Select(it => new QmsBusiIpqcinspectionListOutput
        {
            id = it.Id,
            type = it.Type,
            code = it.Code,
            date = it.Date,
            workshopId = it.WorkshopId,
            teamId = it.TeamId,
            workshopSectionId = it.WorkshopSectionId,
            stationId = it.StationId,
            processIdList = it.ProcessIdList,
            materialCode = it.MaterialCode,
            inspectionCase = it.InspectionCase,
            productionQty = it.ProductionQty,
            employeeCode = it.EmployeeCode,
            employeeName = it.EmployeeName,
            orderNo = it.OrderNo,
            remark = it.Remark,
            status = it.Status,
            overdue = it.Overdue,
            closeFlag = it.CloseFlag,
            dayFlag = it.DayFlag,
            dayValue = it.DayValue,
            hourFlag = it.HourFlag,
            hourValue = it.HourValue,
        }).OrderByIF(!string.IsNullOrEmpty(input.sidx), it => input.sidx + " " + input.sort).ToListAsync();

        return data;
    }

    /// <summary>
    /// 导出制程报检单.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("Actions/Export")]
    public async Task<dynamic> Export([FromQuery] QmsBusiIpqcinspectionListQueryInput input)
    {
        var exportData = new List<QmsBusiIpqcinspectionListOutput>();
        if (input.dataType == 0)
            exportData = Clay.Object(await GetList(input)).Solidify<PageResult<QmsBusiIpqcinspectionListOutput>>().list;
        else
            exportData = await GetNoPagingList(input);
        List<ParamsModel> paramList = "[{\"value\":\"报检单号\",\"field\":\"code\"},{\"value\":\"报价日期\",\"field\":\"date\"},{\"value\":\"报检类型\",\"field\":\"type\"},{\"value\":\"⻋间\",\"field\":\"workshopId\"},{\"value\":\"班组\",\"field\":\"teamId\"},{\"value\":\"⼯段\",\"field\":\"workshopSectionId\"},{\"value\":\"⼯位\",\"field\":\"stationId\"},{\"value\":\"物料\",\"field\":\"materialCode\"},{\"value\":\"⼯序\",\"field\":\"processIdList\"},{\"value\":\"检验⽅案Guid\",\"field\":\"inspectionCase\"},{\"value\":\"⽣产数量\",\"field\":\"productionQty\"},{\"value\":\"检验员\",\"field\":\"employeeCode\"},{\"value\":\"检验员名称\",\"field\":\"employeeName\"},{\"value\":\"⽣产订单号\",\"field\":\"orderNo\"},{\"value\":\"备注\",\"field\":\"remark\"},{\"value\":\"状态\",\"field\":\"status\"},{\"value\":\"逾期状态\",\"field\":\"overdue\"},{\"value\":\"⾃动关闭\",\"field\":\"closeFlag\"},{\"value\":\"天标识\",\"field\":\"dayFlag\"},{\"value\":\"天值\",\"field\":\"dayValue\"},{\"value\":\"小时标识\",\"field\":\"hourFlag\"},{\"value\":\"小时值\",\"field\":\"hourValue\"},]".ToList<ParamsModel>();
        ExcelConfig excelconfig = new ExcelConfig();
        excelconfig.FileName = "制程报检单.xls";
        excelconfig.HeadFont = "微软雅黑";
        excelconfig.HeadPoint = 10;
        excelconfig.IsAllSizeColumn = true;
        excelconfig.ColumnModel = new List<ExcelColumnModel>();
        foreach (var item in input.selectKey.Split(',').ToList())
        {
            var isExist = paramList.Find(p => p.field == item);
            if (isExist != null)
                excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field, ExcelColumn = isExist.value });
        }

        var addPath = FileVariable.TemporaryFilePath + excelconfig.FileName;
        ExcelExportHelper<QmsBusiIpqcinspectionListOutput>.Export(exportData, excelconfig, addPath);
        var fileName = _userManager.UserId + "|" + addPath + "|xls";
        return new
        {
            name = excelconfig.FileName,
            url = "/api/File/Download?encryption=" + DESCEncryption.Encrypt(fileName, "SHZY")
        };
    }

    /// <summary>
    /// 批量删除制程报检单.
    /// </summary>
    /// <param name="ids">主键数组.</param>
    /// <returns></returns>
    [HttpPost("batchRemove")]
    public async Task BatchRemove([FromBody] List<string> ids)
    {
        var entitys = await _repository.Context.Queryable<QmsBusiIpqcinspectionEntity>().In(it => it.Id, ids).ToListAsync();
        if (entitys.Count > 0)
        {
            try
            {
                // 开启事务
                _repository.Context.BeginTran();

                // 批量删除制程报检单
                var isOk = await _repository.Context.Updateable<QmsBusiIpqcinspectionEntity>().SetColumns(it => new QmsBusiIpqcinspectionEntity()
                {
                    DeleteTime = DateTime.Now,
                    DeleteMark = 1,
                    DeleteUserId = _userManager.UserId
                }).Where(it => ids.Contains(it.Id)).ExecuteCommandHasChangeAsync();

                // 关闭事务
                _repository.Context.CommitTran();
            }
            catch (Exception)
            {
                // 回滚事务
                _repository.Context.RollbackTran();

                throw Oops.Oh(ErrorCode.COM1002);
            }
        }
    }

    /// <summary>
    /// 更新制程报检单.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPut("{id}")]
    public async Task Update(string id, [FromBody] QmsBusiIpqcinspectionUpInput input)
    {
        var entity = input.Adapt<QmsBusiIpqcinspectionEntity>();
        if (string.IsNullOrEmpty(entity.EmployeeCode))
        {
            if (!GetInspector(entity).Result)
            {
                throw Oops.Oh("报检单未匹配到检验员，请确认");
            }
        }
        else
        {
            var userInfo = await _repository.Context.Queryable<UserEntity>().Where(it => it.Id == entity.EmployeeCode).FirstAsync();
            entity.EmployeeCode = userInfo.Account;
            entity.EmployeeName = userInfo.RealName;

        }
        var isOk = await _repository.Context.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
        if (!isOk)
            throw Oops.Oh(ErrorCode.COM1001);
    }

    /// <summary>
    /// 删除制程报检单.
    /// </summary>
    /// <returns></returns>
    [HttpDelete("{id}")]
    public async Task Delete(string id)
    {
        var isOk = await _repository.Context.Updateable<QmsBusiIpqcinspectionEntity>().SetColumns(it => new QmsBusiIpqcinspectionEntity()
        {
            DeleteTime = DateTime.Now,
            DeleteMark = 1,
            DeleteUserId = _userManager.UserId
        }).Where(x => x.Id == id).ExecuteCommandHasChangeAsync();
        if (!isOk)
            throw Oops.Oh(ErrorCode.COM1002);
    }


    /// <summary>
    /// 确认报检单.
    /// </summary>
    /// <param name="ids">主键数组.</param>
    /// <returns></returns>
    [HttpPost("confirm")]
    public async Task Confirm([FromBody] List<string> ids)
    {
        var entitys = await _repository.Context.Queryable<QmsBusiIpqcinspectionEntity>().Where(it => it.Status == 0).In(it => it.Id, ids).ToListAsync();
        
        try
        {
            // 开启事务
            _repository.Context.BeginTran();
            foreach (var entity in entitys)
            {
                if (entity.DayFlag.Equals("Y") || entity.HourFlag.Equals("Y"))
                {
                    var isOk = await _repository.Context.Updateable<QmsBusiIpqcinspectionEntity>().SetColumns(it => new QmsBusiIpqcinspectionEntity()
                    {
                        Status = 1,
                        LastModifyTime = DateTime.Now,
                        LastModifyUserId = _userManager.UserId
                    }).Where(x => x.Id == entity.Id).ExecuteCommandHasChangeAsync();
                }
                else
                {
                    // 生成检验单
                    await GenerateChecklist(entity);

                    var isOk = await _repository.Context.Updateable<QmsBusiIpqcinspectionEntity>().SetColumns(it => new QmsBusiIpqcinspectionEntity()
                    {
                        Status = 2,
                        LastModifyTime = DateTime.Now,
                        LastModifyUserId = _userManager.UserId
                    }).Where(x => x.Id == entity.Id).ExecuteCommandHasChangeAsync();
                }
            }
            // 关闭事务
            _repository.Context.CommitTran();
        }
        catch (Exception ex)
        {
            // 回滚事务
            _repository.Context.RollbackTran();

            throw Oops.Oh(ex.Message);
        }
    }

    /// <summary>
    /// 生成检验单
    /// </summary>
    /// <param name="entity">制程报检单</param>
    /// <returns></returns>
    [NonAction]
    public async Task<dynamic> GenerateChecklist(QmsBusiIpqcinspectionEntity entity,bool isLogin = true)
    {
        // 查询检验方案
        var checkcardEntity = new QmsBaseCheckcardEntity();
        if (!string.IsNullOrEmpty(entity.InspectionCase))
        {
            checkcardEntity = await _repository.Context.Queryable<QmsBaseCheckcardEntity>().Where(x => x.Id == entity.InspectionCase  && x.DeleteMark == null && x.EnabledMark == 1).OrderBy(x => x.CreatorTime, OrderByType.Desc).FirstAsync();
        }
        else
        {
            checkcardEntity = await _repository.Context.Queryable<QmsBaseCheckcardEntity, QmsBaseCheckcardmaterialEntity>((a, b) => new JoinQueryInfos(JoinType.Inner, a.Id == b.ParentId && b.DeleteMark == null && b.EnabledMark == 1))
                .Where((a, b) => b.MaterialCode == entity.MaterialCode && a.Business.Contains("IPQC") && a.DeleteMark == null && a.EnabledMark == 1)
                .OrderBy((a, b) => a.CreatorTime, OrderByType.Desc).Select((a, b) => a).FirstAsync();
        }

        if (checkcardEntity == null)
        {
            throw Oops.Oh("未查询到检验方案");
        }

        // 查询检验方案的检验项目
        var checkcarddetailList = await _repository.Context.Queryable<QmsBaseCheckcardsampleEntity, QmsBaseCheckcarddetailEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.Id == b.SampleId))
            .Where((a, b) => a.CheckGuid == checkcardEntity.Id && a.DeleteMark == null && a.EnabledMark == 1)
            .Where((a, b) => !string.IsNullOrEmpty(b.Id) && b.DeleteMark == null && b.EnabledMark == 1)
            .OrderBy((a, b) => a.CreatorTime, OrderByType.Desc)
            .Select((a, b) => new QmsBaseCheckcarddetailInfoGenerateOutput
            {
                id = b.Id,
                sampleId = b.SampleId,
                samplingType = a.SamplingType,
                gLevel = a.GLevel,
                gStringency = a.GStringency,
                gQualityLimit = a.GQualityLimit,
                fixedSamplingQty = a.FixedSamplingQty,
                fixedRatio = a.FixedRatio,
                aql = a.Aql,
                innspectionName = b.InnspectionName,
                innspectionEntry = b.InnspectionEntry,
                innspectionMethod = b.InnspectionMethod,
                type = b.Type,
                quantitativeStandards = b.QuantitativeStandards,
                standardValue = b.StandardValue,
                upperDeviation = b.UpperDeviation,
                lowerDeviation = b.LowerDeviation,
                maximumValue = b.MaximumValue,
                minimumValue = b.MinimumValue,
                accuracy = b.Accuracy,
                unit = b.Unit,
                remarks = b.Remarks,
                referTo = b.ReferTo,
                destructiveness = b.Destructiveness,
                customParameters = b.CustomParameters,
                qualifyingLogic = b.QualifyingLogic,
                supplier = b.Supplier,
                customer = b.Customer,
                businessType = b.BusinessType,
                sort = b.Sort,
                volt = b.Volt,
                formula = b.Formula,
                vType = b.VType,
                fileInfo1 = b.FileInfo,
                enabledMark = b.EnabledMark

            }).ToListAsync();
        if (checkcarddetailList.Count <= 0)
        {
            throw Oops.Oh("检验方案未查询到检验项目");
        }

       

        // 填充检验批数据
        QmsBusiIpqcinspectionlotEntity _qmsBusiIpqcinspectionlotEntity = new QmsBusiIpqcinspectionlotEntity();
        _qmsBusiIpqcinspectionlotEntity.Code = await _billRullService.GetBillNumber("zhichengjianyandan", false, isLogin);
        _qmsBusiIpqcinspectionlotEntity.InspectionCode = entity.Code;
        _qmsBusiIpqcinspectionlotEntity.Type = "IPQC";
        _qmsBusiIpqcinspectionlotEntity.InspectType = entity.Type;
        _qmsBusiIpqcinspectionlotEntity.Date = DateTime.Now;
        _qmsBusiIpqcinspectionlotEntity.WorkshopId = entity.WorkshopId;
        _qmsBusiIpqcinspectionlotEntity.TeamId = entity.TeamId;
        _qmsBusiIpqcinspectionlotEntity.WorkshopSectionId = entity.WorkshopSectionId;
        _qmsBusiIpqcinspectionlotEntity.StationId = entity.StationId;
        _qmsBusiIpqcinspectionlotEntity.ProcessIdList = entity.ProcessIdList;
        _qmsBusiIpqcinspectionlotEntity.MaterialCode = entity.MaterialCode;
        _qmsBusiIpqcinspectionlotEntity.OrderNo = entity.OrderNo;
        _qmsBusiIpqcinspectionlotEntity.ProductionQty = entity.ProductionQty;
        _qmsBusiIpqcinspectionlotEntity.EmployeeCode = entity.EmployeeCode;
        _qmsBusiIpqcinspectionlotEntity.EmployeeName = entity.EmployeeName;
        _qmsBusiIpqcinspectionlotEntity.Remark = "";
        _qmsBusiIpqcinspectionlotEntity.Status = 0;
        _qmsBusiIpqcinspectionlotEntity.CloseDes = "";
        _qmsBusiIpqcinspectionlotEntity.Overdue = 0;
        _qmsBusiIpqcinspectionlotEntity.MaterialFile = "[]";

        // 查询物料附件
        if (!string.IsNullOrEmpty(_qmsBusiIpqcinspectionlotEntity.MaterialCode))
        {
            var materialInfo = await _repository.Context.Queryable<QmsBaseMaterialEntity>().Where(x => x.Code == _qmsBusiIpqcinspectionlotEntity.MaterialCode && x.DeleteMark == null).FirstAsync();
            if (materialInfo != null)
            {
                _qmsBusiIpqcinspectionlotEntity.MaterialFile = materialInfo.FileInfo;
            }
        }
        _qmsBusiIpqcinspectionlotEntity.CheckCardFile = checkcardEntity.FileInfo;

        // 以下信息这样填写是考虑到作业调度任务没有登录信息
        _qmsBusiIpqcinspectionlotEntity.Id = YitIdHelper.NextId().ToString();
        _qmsBusiIpqcinspectionlotEntity.CreatorUserId = isLogin ? _userManager.UserId : "system";
        _qmsBusiIpqcinspectionlotEntity.CreatorTime =DateTime.Now;
        _qmsBusiIpqcinspectionlotEntity.EnabledMark = 1;

        List<QmsBusiIpqcinspectionitemEntity> _qmsBusiIpqcinspectionitemEntityList = new List<QmsBusiIpqcinspectionitemEntity>();

        // 获取抽样方案字典项
        var sampleTypeList = await _dictionaryDataService.GetList("sampleType");

        // 获取匹配的检验项目
        foreach (var item in checkcarddetailList)
        {
            // 如果开启了限定逻辑，则校验限定业务类型是否与当前报检单类型一致
            if (!string.IsNullOrEmpty(item.qualifyingLogic) && item.qualifyingLogic.Equals("Y") && !string.IsNullOrEmpty(item.businessType))
            {
                string[] businessTypeList = item.businessType.Split(',');
                if (!businessTypeList.Contains(entity.Type))
                {
                    continue;
                }
            }

            // 填充检验项目数据
            QmsBusiIpqcinspectionitemEntity _qmsBusiIpqcinspectionitemEntity = new QmsBusiIpqcinspectionitemEntity();
            _qmsBusiIpqcinspectionitemEntity.Code = _qmsBusiIpqcinspectionlotEntity.Code;
            _qmsBusiIpqcinspectionitemEntity.Type = item.type;
            _qmsBusiIpqcinspectionitemEntity.SampleId = item.sampleId;
            _qmsBusiIpqcinspectionitemEntity.SamplingType = item.samplingType;

            var sampleTypeObj = sampleTypeList.Find(d => d.EnCode.Equals(item.samplingType));
            _qmsBusiIpqcinspectionitemEntity.SamplingTypeDes = sampleTypeObj == null ? "" : sampleTypeObj.FullName;

            _qmsBusiIpqcinspectionitemEntity.InnspectionCode = item.innspectionName;
            _qmsBusiIpqcinspectionitemEntity.InnspectionEntry = item.innspectionEntry;
            _qmsBusiIpqcinspectionitemEntity.InnspectionMethod = item.innspectionMethod;

            // 获取检验项目名称
            var innspectionitemsEntity = await _repository.Context.Queryable<QmsBaseInnspectionitemsEntity>().Where(x => x.Id == item.innspectionName).FirstAsync();
            if (innspectionitemsEntity == null)
                throw Oops.Oh("未查询到检验项目名称");
            _qmsBusiIpqcinspectionitemEntity.InnspectionName = innspectionitemsEntity.InnspectionName;

            // 获取检验条目名称
            var innspectionentryEntity = await _repository.Context.Queryable<QmsBaseInnspectionentryEntity>().Where(x => x.Id == item.innspectionEntry).FirstAsync();
            if (innspectionentryEntity == null)
                throw Oops.Oh("未查询到检验条目名称");
            _qmsBusiIpqcinspectionitemEntity.InnspectionEntryName = innspectionentryEntity.InnspectionName;

            // 获取检验方法名称
            var innspectionmethodEntity = await _repository.Context.Queryable<QmsBaseInnspectionmethodEntity>().Where(x => x.Id == item.innspectionMethod).FirstAsync();
            if(innspectionmethodEntity == null)
                throw Oops.Oh("未查询到检验方法名称");
            _qmsBusiIpqcinspectionitemEntity.InnspectionMethodName = innspectionmethodEntity.Name;

            _qmsBusiIpqcinspectionitemEntity.QuantitativeStandards = item.quantitativeStandards;
            _qmsBusiIpqcinspectionitemEntity.StandardValue = item.standardValue;
            _qmsBusiIpqcinspectionitemEntity.UpperDeviation = item.upperDeviation;
            _qmsBusiIpqcinspectionitemEntity.LowerDeviation = item.lowerDeviation;
            _qmsBusiIpqcinspectionitemEntity.MaximumValue = item.maximumValue;
            _qmsBusiIpqcinspectionitemEntity.MinimumValue = item.minimumValue;
            _qmsBusiIpqcinspectionitemEntity.Unit = item.unit;
            _qmsBusiIpqcinspectionitemEntity.Accuracy = item.accuracy;
            _qmsBusiIpqcinspectionitemEntity.FileInfo = item.fileInfo1;
            _qmsBusiIpqcinspectionitemEntity.SamplingQty = 0;// 抽样数量
            _qmsBusiIpqcinspectionitemEntity.ReceivedQty = 0;
            _qmsBusiIpqcinspectionitemEntity.RejectionQty = 0;
            _qmsBusiIpqcinspectionitemEntity.Remarks = item.remarks;
            _qmsBusiIpqcinspectionitemEntity.ReferTo = item.referTo;
            _qmsBusiIpqcinspectionitemEntity.Destructiveness = item.destructiveness ?? "N";
            _qmsBusiIpqcinspectionitemEntity.DestructivenessQty = 0;
            _qmsBusiIpqcinspectionitemEntity.Sort = item.sort;
            _qmsBusiIpqcinspectionitemEntity.Volt = item.volt;
            _qmsBusiIpqcinspectionitemEntity.VType = item.vType;
            _qmsBusiIpqcinspectionitemEntity.Formula = item.formula;
            _qmsBusiIpqcinspectionitemEntity.Parameter = item.customParameters;
            _qmsBusiIpqcinspectionitemEntity.Exempt = "N";
            _qmsBusiIpqcinspectionitemEntity.AutoFlag = "Y";

            // 以下信息这样填写是考虑到作业调度任务没有登录信息
            _qmsBusiIpqcinspectionitemEntity.Id = YitIdHelper.NextId().ToString();
            _qmsBusiIpqcinspectionitemEntity.CreatorUserId = isLogin ? _userManager.UserId : "system";
            _qmsBusiIpqcinspectionitemEntity.CreatorTime = DateTime.Now;
            _qmsBusiIpqcinspectionitemEntity.EnabledMark = 1;

            // 获取抽样数量
            GetSampleQty(entity, _qmsBusiIpqcinspectionitemEntity, item);

            _qmsBusiIpqcinspectionitemEntityList.Add(_qmsBusiIpqcinspectionitemEntity);
        }

        if (_qmsBusiIpqcinspectionitemEntityList.Count <= 0)
        {
            throw Oops.Oh("检验方案未匹配到检验项目");
        }

        var isOk1 = await _repository.Context.Insertable(_qmsBusiIpqcinspectionlotEntity).ExecuteCommandAsync();
        if (!(isOk1 > 0)) throw Oops.Oh("新增检验批失败");

        var isOk2 = await _repository.Context.Insertable(_qmsBusiIpqcinspectionitemEntityList).ExecuteCommandAsync();
        if (!(isOk2 > 0)) throw Oops.Oh("新增检验批检验项目失败");

        // 处理推送消息
        var userInfo = await _repository.Context.Queryable<UserEntity>().Where(it => it.Account == entity.EmployeeCode).FirstAsync();
        JArray jArray = new JArray();
        JObject jObject = new JObject();
        jObject.Add("name", "制程检验单");
        jObject.Add("code", _qmsBusiIpqcinspectionlotEntity.Code);
        jObject.Add("status", "待检验");
        jObject.Add("userName", isLogin ? _userManager.RealName : "system");
        jObject.Add("date", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
        jArray.Add(jObject);
        _messageService.AddMessageEvent("Inspection", userInfo.Id, jArray.ToJsonString(), null, isLogin);

        return true;
    }

    /// <summary>
    /// 获取抽样数量
    /// </summary>
    /// <returns></returns>
    [NonAction]
    private async Task<bool> GetSampleQty(QmsBusiIpqcinspectionEntity _qmsBusiIpqcinspectionEntity, QmsBusiIpqcinspectionitemEntity _qmsBusiIpqcinspectionitemEntity, QmsBaseCheckcarddetailInfoGenerateOutput _qmsBaseCheckcarddetailInfoGenerateOutput)
    {
        int productionQty = _qmsBusiIpqcinspectionEntity.ProductionQty ?? 0;
        int samplingQty = 0;
        int receivedQty = 0;
        int rejectionQty = 0;
        string samplingType = _qmsBaseCheckcarddetailInfoGenerateOutput.samplingType;
        string gLevel = _qmsBaseCheckcarddetailInfoGenerateOutput.gLevel;
        string gStringency = _qmsBaseCheckcarddetailInfoGenerateOutput.gStringency;
        string gQualityLimit = _qmsBaseCheckcarddetailInfoGenerateOutput.gQualityLimit;
        int fixedSamplingQty = _qmsBaseCheckcarddetailInfoGenerateOutput.fixedSamplingQty ?? 0;
        decimal fixedRatio = _qmsBaseCheckcarddetailInfoGenerateOutput.fixedRatio;
        string aQL = _qmsBaseCheckcarddetailInfoGenerateOutput.aql;

        // 1 国标AQL
        // 2 固定抽样
        // 3 固定比例
        // 4 自定义AQL
        // 5 执行时自行设置
        if (samplingType.Equals("1"))
        {
            var nationalstandard = await _repository.Context.Queryable<QmsBaseNationalstandardEntity>()
                             .Where(x => x.InspectionLevel == gLevel && x.Stage == gStringency && x.QualityLimit == gQualityLimit && x.LowerLimit <= productionQty && x.UpperLimit >= productionQty && x.DeleteMark == null && x.EnabledMark == 1).FirstAsync();
            if (nationalstandard == null)
                throw Oops.Oh("未匹配到国标抽样方案");
            // 全检则抽样数量等于来料数量
            if (nationalstandard.AllInspection.Equals("Y"))
            {
                samplingQty = productionQty;
                receivedQty = samplingQty;
            }
            else
            {
                samplingQty = nationalstandard.SampleQty ?? 0;
                receivedQty = nationalstandard.ReceivedQty ?? 0;
            }
            rejectionQty = 0;
        }
        else if (samplingType.Equals("2"))
        {
            samplingQty = fixedSamplingQty;
            receivedQty = samplingQty;
            rejectionQty = 1;
        }
        else if (samplingType.Equals("3"))
        {
            samplingQty = (int)Math.Ceiling(productionQty * (fixedRatio / 100));//向上取整
            receivedQty = samplingQty;
            rejectionQty = 1;
        }
        else if (samplingType.Equals("4"))
        {
            var samplingplandetail = await _repository.Context.Queryable<QmsBaseSamplingplanEntity, QmsBaseSamplingplandetailEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.Id == b.MainId))
                .Where((a, b) => a.Id == aQL && b.LowerLimit <= productionQty && b.UpperLimit >= productionQty && a.DeleteMark == null && a.EnabledMark == 1 && b.DeleteMark == null && b.EnabledMark == 1).Select((a, b) => b).FirstAsync();
            if (samplingplandetail == null)
                throw Oops.Oh("未匹配到自定义AQL抽样方案");

            samplingQty = samplingplandetail.SampleQty ?? 0;
            receivedQty = samplingplandetail.ReceivedQty ?? 0;
            rejectionQty = samplingplandetail.RejectionQty ?? 0;

        }
        else if (samplingType.Equals("5"))
        {
            samplingQty = Convert.ToInt32(fixedSamplingQty);
            receivedQty = samplingQty;
            rejectionQty = 1;
        }

        if (samplingQty > productionQty)
            throw Oops.Oh("计数抽样数量结果：抽样数量大于生产数量，请检查");

        _qmsBusiIpqcinspectionitemEntity.SamplingQty = samplingQty;
        _qmsBusiIpqcinspectionitemEntity.ReceivedQty = receivedQty;
        _qmsBusiIpqcinspectionitemEntity.RejectionQty = rejectionQty;
        return true;
    }



    /// <summary>
    /// 获取检验员看板数据.
    /// </summary>
    /// <returns></returns>
    [HttpGet("InspectorKanban")]
    public async Task<dynamic> InspectorKanban()
    {
        // 查询报检单已经分配的检验员

        var queryable1 = _repository.Context.Queryable<QmsBusiIpqcinspectionEntity>()
            .Where(x => !string.IsNullOrEmpty(x.EmployeeCode) && (x.Status == 0 || x.Status == 1) && x.DeleteMark == null && x.EnabledMark == 1)
            .GroupBy(a => new { a.EmployeeCode })
            .Select(a => new QmsBusiIpqcinspectionListOutput
            {
                employeeCode = a.EmployeeCode
            });
        var queryable2 = _repository.Context.Queryable<QmsBusiIpqcinspectionlotEntity>()
            .Where(x => !string.IsNullOrEmpty(x.EmployeeCode) && (x.Status == 0 || x.Status == 1) && x.DeleteMark == null && x.EnabledMark == 1)
            .GroupBy(a => new { a.EmployeeCode })
            .Select(a => new QmsBusiIpqcinspectionListOutput
            {
                employeeCode = a.EmployeeCode
            });

        var inspectorList = await _repository.Context.Union(queryable1, queryable2).OrderBy(x=>x.employeeCode,OrderByType.Asc).ToListAsync();

        JArray jArray = new JArray();
        int total = 0;
        foreach (var item in inspectorList)
        {
            JArray jArray1 = new JArray();
            var ipqcinspectionList = await _repository.Context.Queryable<QmsBusiIpqcinspectionEntity, QmsBaseMaterialEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.MaterialCode == b.Code && b.DeleteMark == null))
            .Where(a => a.EmployeeCode == item.employeeCode && (a.Status == 0 || a.Status == 1) && a.DeleteMark == null && a.EnabledMark == 1)
            .OrderBy(a => a.Date, OrderByType.Asc)
            .Select((a,b) => new QmsBusiIpqcinspectionListOutput
            {
                id = a.Id,
                code = a.Code,
                materialCode = SqlFunc.IsNull(SqlFunc.MergeString(b.Name, " ", b.Code), a.MaterialCode),
                orderNo = a.OrderNo,
                productionQty = a.ProductionQty,
                date = a.Date,
                overdue = a.Overdue
            }).ToListAsync();

            foreach (var ipqcinspection in ipqcinspectionList)
            {
                JObject jObject1 = new JObject();
                jObject1.Add("type", 1);
                jObject1.Add("id", ipqcinspection.id);
                jObject1.Add("code", ipqcinspection.code);
                jObject1.Add("materialCode", ipqcinspection.materialCode);
                jObject1.Add("orderNo", ipqcinspection.orderNo);
                jObject1.Add("productionQty", ipqcinspection.productionQty);
                jObject1.Add("date", ipqcinspection.date);
                jObject1.Add("overdue", ipqcinspection.overdue);
                jArray1.Add(jObject1);
            }

            var ipqcinspectionlotList = await _repository.Context.Queryable<QmsBusiIpqcinspectionlotEntity, QmsBaseMaterialEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.MaterialCode == b.Code && b.DeleteMark == null))
            .Where(a => a.EmployeeCode == item.employeeCode && (a.Status == 0 || a.Status == 1) && a.DeleteMark == null && a.EnabledMark == 1)
            .OrderBy(a => a.CreatorTime, OrderByType.Asc)
            .Select((a, b) => new QmsBusiIpqcinspectionlotListOutput
            {
                id = a.Id,
                code = a.Code,
                materialCode = SqlFunc.IsNull(SqlFunc.MergeString(b.Name, " ", b.Code), a.MaterialCode),
                orderNo = a.OrderNo,
                productionQty = a.ProductionQty,
                date = a.Date,
                overdue = a.Overdue
            }).ToListAsync();

            foreach (var ipqcinspectionlot in ipqcinspectionlotList)
            {
                JObject jObject1 = new JObject();
                jObject1.Add("type", 2);
                jObject1.Add("id", ipqcinspectionlot.id);
                jObject1.Add("code", ipqcinspectionlot.code);
                jObject1.Add("materialCode", ipqcinspectionlot.materialCode);
                jObject1.Add("orderNo", ipqcinspectionlot.orderNo);
                jObject1.Add("productionQty", ipqcinspectionlot.productionQty);
                jObject1.Add("date", ipqcinspectionlot.date);
                jObject1.Add("overdue", ipqcinspectionlot.overdue);
                jArray1.Add(jObject1);
            }

            var count = ipqcinspectionList.Count + ipqcinspectionlotList.Count;
            total += count;

            var userInfo = await _repository.Context.Queryable<UserEntity>().Where(x => x.Account == item.employeeCode && x.DeleteMark == null).FirstAsync();

            JObject jObject = new JObject();
            jObject.Add("employeeCode", item.employeeCode);
            jObject.Add("employeeName", userInfo?.RealName);
            jObject.Add("headIcon", userInfo?.HeadIcon);
            jObject.Add("count", count);
            jObject.Add("list", jArray1);
            jArray.Add(jObject);
        }

        // 未分配的
        var waitList = await _repository.Context.Queryable<QmsBusiIpqcinspectionEntity, QmsBaseMaterialEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.MaterialCode == b.Code))
            .Where((a, b) => string.IsNullOrEmpty(a.EmployeeCode) && a.DeleteMark == null && a.EnabledMark == 1).OrderBy(a => a.Date, OrderByType.Asc).Select((a, b) => new
            {
                type = 1,
                id = a.Id,
                code = a.Code,
                materialCode = SqlFunc.IsNull(SqlFunc.MergeString(b.Name, " ", b.Code), a.MaterialCode),
                orderNo = a.OrderNo,
                productionQty = a.ProductionQty,
                date = a.Date,
                overdue = a.Overdue
            }).ToListAsync();

        // 已完成检验
        var finishList = await _repository.Context.Queryable<QmsBusiIpqcinspectionlotEntity>()
            .GroupBy(x => new { x.EmployeeCode })
            .Where(x => !string.IsNullOrEmpty(x.EmployeeCode) && (x.Status == 2 || x.Status == 3) && x.DeleteMark == null && x.EnabledMark == 1)
            .OrderBy(x => x.EmployeeCode, OrderByType.Asc)
            .Select(x => new
            {
                employeeCode = x.EmployeeCode,
                employeeName = SqlFunc.Subqueryable<UserEntity>().Where(a => a.Account == x.EmployeeCode && a.DeleteMark == null ).Select(a => a.RealName),
                headIcon = SqlFunc.Subqueryable<UserEntity>().Where(a => a.Account == x.EmployeeCode && a.DeleteMark == null).Select(a => a.HeadIcon),
                count = SqlFunc.AggregateCount(x.EmployeeCode)
            }).ToListAsync();

        return new { list = jArray, total = total, wait = waitList, finish = finishList };
    }

    /// <summary>
    /// 分配检验员.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPut("AssignInspector")]
    public async Task AssignInspector([FromBody] JObject _data)
    {
        string id= _data["id"].ToString();
        string employeeCode = _data["employeeCode"].ToString(); 
        string employeeName = _data["employeeName"].ToString();
        string type = _data["type"].ToString();

        // 如果是检验批则更新检验批
        if (type.Equals("2"))
        {
            var isOk = await _repository.Context.Updateable<QmsBusiIpqcinspectionlotEntity>().SetColumns(it => new QmsBusiIpqcinspectionlotEntity()
            {
                EmployeeCode = employeeCode,
                EmployeeName = employeeName,
                LastModifyTime = DateTime.Now,
                LastModifyUserId = _userManager.UserId
            }).Where(x => x.Id == id && (x.Status == 0 || x.Status == 1) && x.DeleteMark == null && x.EnabledMark == 1).ExecuteCommandHasChangeAsync();
            if (!isOk)
                throw Oops.Oh(ErrorCode.COM1001);
        }
        else
        {
            // 否则更新报检单
            var isOk = await _repository.Context.Updateable<QmsBusiIpqcinspectionEntity>().SetColumns(it => new QmsBusiIpqcinspectionEntity()
            {
                EmployeeCode = employeeCode,
                EmployeeName = employeeName,
                LastModifyTime = DateTime.Now,
                LastModifyUserId = _userManager.UserId
            }).Where(x => x.Id == id).ExecuteCommandHasChangeAsync();
            if (!isOk)
                throw Oops.Oh(ErrorCode.COM1001);
        }
    }

    /// <summary>
    /// 制程检验按天生成检验批
    /// </summary>
    /// <returns></returns>
    [NonAction]
    public async Task<dynamic> GenerateInspectionDay()
    {
        // 查询当前天的日历信息
        var currentTime = DateTime.Now;
        var day = currentTime.ToString("yyyy-MM-dd");
        var dayInfo = await _repository.Context.Queryable<QmsbaseIpqccalendarDetailEntity>().Where(x => x.Date == SqlFunc.ToDate(day) && x.DeleteMark == null & x.EnabledMark == 1).FirstAsync();
        if(dayInfo == null )
        {
            throw Oops.Oh("工作日历未维护：" + day);
        }

        // 休息日，法定假日不生成检验批
        if(dayInfo.DateType==1 || dayInfo.DateType == 2)
        {
            return true;
        }

        // 查询按天生成检验批的报检单
        var ipqcinspectionList = await _repository.Context.Queryable<QmsBusiIpqcinspectionEntity>().Where(x => x.DayFlag == "Y" && x.DayValue != 0 && x.Status == 1 && x.DeleteMark == null && x.EnabledMark == 1).ToListAsync();
        foreach (var item in ipqcinspectionList)
        {
            // 获取最新生成的检验批的创建时间计数时隔天数，大于等于配置的天数间隔则生成检验批
            var ipqcinspectionlotEntity = await _repository.Context.Queryable<QmsBusiIpqcinspectionlotEntity>().Where(x => x.InspectionCode == item.Code && x.DeleteMark == null && x.EnabledMark == 1).OrderBy(x => x.CreatorTime, OrderByType.Desc).FirstAsync();
            if (ipqcinspectionlotEntity != null)
            {
                var dayValue = (currentTime - ipqcinspectionlotEntity.CreatorTime)?.TotalDays;
                if (dayValue >= item.DayValue)
                {
                    GenerateChecklist(item, false);
                }
            }
            else
            {
                // 第一次生成检验批，不用判断天数间隔，直接生成检验批
                GenerateChecklist(item, false);
            }
        }
        return true;
    }

    /// <summary>
    /// 制程检验按小时生成检验批
    /// </summary>
    /// <returns></returns>
    [NonAction]
    public async Task<dynamic> GenerateInspectionHour()
    {
        // 查询当前天的日历信息
        var currentTime = DateTime.Now;
        var day = currentTime.ToString("yyyy-MM-dd");
        var dayInfo = await _repository.Context.Queryable<QmsbaseIpqccalendarDetailEntity>().Where(x => x.Date == SqlFunc.ToDate(day) && x.DeleteMark == null & x.EnabledMark == 1).FirstAsync();
        if (dayInfo == null)
        {
            throw Oops.Oh("工作日历未维护：" + day);
        }

        // 休息日，法定假日不生成检验批
        if (dayInfo.DateType == 1 || dayInfo.DateType == 2)
        {
            return true;
        }

        // 查询工作时间
        var year = currentTime.Year;
        var worktimeList =await _repository.Context.Queryable<QmsBaseIpqccalendarworktimeEntity>().Where(x => x.Year == year && x.DeleteMark == null & x.EnabledMark == 1).OrderBy(x=>x.StartTime).ToListAsync();
        if(worktimeList.Count <= 0)
        {
            throw Oops.Oh("工作时间未维护");
        }

        // 判断当前时间是否在工作时间内
        bool judgeResult = false;
        foreach (var item in worktimeList)
        {
            var startTime = DateTime.Parse(day + " " + item.StartTime);
            var endTime = DateTime.Parse(day + " " + item.EndTime);
            if (currentTime >= startTime && currentTime <= endTime)
            {
                judgeResult = true;
                break;
            }
        }

        // 不在工作时间内不生成检验批
        if (!judgeResult)
        {
            return true;
        }

        // 查询按小时生成检验批的报检单
        var ipqcinspectionList = await _repository.Context.Queryable<QmsBusiIpqcinspectionEntity>().Where(x => x.HourFlag == "Y" && x.HourValue != 0 && x.Status == 1 && x.DeleteMark == null && x.EnabledMark == 1).ToListAsync();
        foreach (var item in ipqcinspectionList)
        {
            // 获取最新生成的检验批的创建时间计数时隔小时数，大于等于配置的小时数间隔则生成检验批
            var ipqcinspectionlotEntity = await _repository.Context.Queryable<QmsBusiIpqcinspectionlotEntity>().Where(x => x.InspectionCode == item.Code && x.DeleteMark == null && x.EnabledMark == 1).OrderBy(x => x.CreatorTime, OrderByType.Desc).FirstAsync();
            if (ipqcinspectionlotEntity != null)
            {

                var hourValue = (currentTime - ipqcinspectionlotEntity.CreatorTime)?.TotalHours;
                if (hourValue >= item.HourValue)
                {
                    GenerateChecklist(item, false);
                }
            }
            else
            {
                // 第一次生成检验批，不用判断小时数间隔，直接生成检验批
                GenerateChecklist(item, false);
            }
        }
        return true;
    }


    /// <summary>
    /// 处理隔日关闭自动生成检验批
    /// </summary>
    /// <returns></returns>
    [NonAction]
    public async Task<dynamic> GenerateInspectionClose()
    {

        // 查询需要隔日关闭自动成检验批的报检单
        var ipqcinspectionList = await _repository.Context.Queryable<QmsBusiIpqcinspectionEntity>().Where(x => x.CloseFlag == "Y" && x.Status == 1 && x.DeleteMark == null && x.EnabledMark == 1).ToListAsync();
        foreach (var item in ipqcinspectionList)
        {
            // 查询是否已经生成过检验批
            var ipqcinspectionlotEntity = await _repository.Context.Queryable<QmsBusiIpqcinspectionlotEntity>().Where(x => x.InspectionCode == item.Code && x.DeleteMark == null && x.EnabledMark == 1).OrderBy(x => x.CreatorTime, OrderByType.Desc).FirstAsync();
            if (ipqcinspectionlotEntity != null)
            {
                // 已经生成过检验批，标识关闭
                var isOk = await _repository.Context.Updateable<QmsBusiIpqcinspectionEntity>().SetColumns(it => new QmsBusiIpqcinspectionEntity()
                {
                    Status = 3,
                    LastModifyTime = DateTime.Now,
                    LastModifyUserId = "system"
                }).Where(x => x.Id == item.Id).ExecuteCommandHasChangeAsync();
                if (!isOk)
                    throw Oops.Oh(ErrorCode.COM1001);
            }
        }
        return true;
    }
}